﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HSDc.RingleFlow.Api.Service;
using HSDc.RingleFlow.Kernel.DBPersit.Dao;
using HSDc.RingleFlow.Api.Kernel;
using NUnit.Framework;

namespace HSDc.RingleFlow.Kernel.DBPersit
{
    //[TestFixture]
    public class TaskServiceImpl : ITaskService
    {
        List<Api.Kernel.ITask> ITaskService.GetTasks(string UserID)
        {
            TaskServiceDao dao = new TaskServiceDao();
            List<ActivityInstanceDto> ais = dao.RetrieveActivityInstances(UserID);
            Dictionary<int, ProcessInstance> dicPi = new Dictionary<int,ProcessInstance>();
            RetrieveProcessInstances(dao, ais, ref dicPi);
            List<ITask> tasks = new List<ITask>();
            ProcessInstance pi = null;
            foreach (ActivityInstanceDto dto in ais)
            {
                dicPi.TryGetValue(dto.ActivityInstance_Belong_ProcessInstance, out pi);
                CheckActivityInstance(ref tasks, pi, dto);
            }
            return tasks;
        }

        private void CheckActivityInstance(ref List<ITask> tasks, ProcessInstance pi, ActivityInstanceDto dto)
        {
            foreach (ActivityInstance ai in pi.GetCurrentTasks())
                if (ai.Id.ToLower().Equals(dto.ActivityInstance_GUID.ToLower()))
                    tasks.Add(ai);
        }

        private void RetrieveProcessInstances(TaskServiceDao dao, List<ActivityInstanceDto> ais, ref Dictionary<int, ProcessInstance> dicPi)
        {
            foreach (ActivityInstanceDto dto in ais)
                if (!dicPi.ContainsKey(dto.ActivityInstance_Belong_ProcessInstance))
                    dicPi.Add(dto.ActivityInstance_Belong_ProcessInstance,
                        RetrieveProcessInstance(dao.RetreiveProcessInstanceIdByGuid(dto.ActivityInstance_Belong_ProcessInstance)));
        }

        ProcessInstance RetrieveProcessInstance(string guid)
        {
            IRuntimeService runtime = new RuntimeServiceImpl();
            return (ProcessInstance)runtime.GetProcessInstance(guid);
        }

        Api.Kernel.ITask ITaskService.GetTask(string UserID, string ProcessInstanceID)
        {
            TaskServiceDao dao = new TaskServiceDao();
            ActivityInstanceDto dto = dao.RetrieveActivityInstance(UserID, ProcessInstanceID);
            return GetSingleTask(dao, dto);
        }

        private ITask GetSingleTask(TaskServiceDao dao, ActivityInstanceDto dto)
        {
            ProcessInstance pi = RetrieveProcessInstance(dao.RetreiveProcessInstanceIdByGuid(dto.ActivityInstance_Belong_ProcessInstance));
            List<ITask> tasks = new List<ITask>();
            CheckActivityInstance(ref tasks, pi, dto);
            return (tasks.Count == 1) ? tasks[0] : null;
        }

        Api.Kernel.ITask ITaskService.GetTask(string TaskID)
        {
            TaskServiceDao dao = new TaskServiceDao();
            ActivityInstanceDto dto = dao.RetrieveActivityInstance(TaskID);
            return GetSingleTask(dao, dto);
        }

        void ITaskService.CompleteTask(Api.Kernel.ITask task)
        {
            ((ActivityInstance)task).Complete();
            // Save to db
            TaskServiceDao dao = new TaskServiceDao();
            dao.CompleteActivityInstance((ActivityInstance)task);
        }

        void ITaskService.SaveTask(Api.Kernel.ITask task)
        {
            // Save to db
            TaskServiceDao dao = new TaskServiceDao();
            dao.SaveActivityInstance((ActivityInstance)task);
        }

        [Test]
        public void TestGetTasks()
        {
            string userId = "ringle";
            ITaskService tasksService = new TaskServiceImpl();
            List<ITask> tasks = tasksService.GetTasks(userId);
        }

        [Test]
        public void TestGetTask()
        {
            string userId = "ringle";
            string piid = "855e8236-1394-4386-bf0b-bae0e04ea8cb";
            ITaskService tasksService = new TaskServiceImpl();
            ITask task = tasksService.GetTask(userId, piid);
        }
    }
}
